home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-07-18 | 4.8 KB | 158 lines |
- // NcgiRequest - read and handle an NCGI request
- //
- // Copyright (c) 1996 Sun Microsystems, Inc. All Rights reserved
- // Permission to use, copy, modify, and distribute this software
- // and its documentation for NON-COMMERCIAL purposes and without
- // fee is hereby granted provided that this copyright notice
- // appears in all copies. Please refer to the file copyright.html
- // for further important copyright and licensing information.
- //
- // SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
- // THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- // PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
- // ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- // DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
-
- package sun.servlet.apache;
-
- import java.io.*;
- import java.util.*;
-
- /** Read and handle an NCGI request.
- ** <P>
- ** This handles the server side of the NCGI protocol. Given an
- ** input stream, it reads the request, does error checking etc.,
- ** and then provides the data.
- ** <P>
- ** The NCGI protocol is fairly simple. There are four parts:
- ** <OL>
- ** <LI>
- ** The first part is to send a "magic" string identifying the protocol
- ** and version. That string is currently "NCGI/1.0". The string is
- ** preceeded by the length as an unsigned short in network order.
- ** <LI>
- ** The second part is authorization.
- ** The server has previously written a random string to a designated file.
- ** The file is protected so that it can only be read by the userid running
- ** the CGI program. That program, the client, reads the file and sends
- ** the entire contents to the server, again preceeded by the length as an
- ** unsigned short in network order.
- ** <LI>
- ** The third part is to send the request.
- ** Since CGI has already encapsulated the request as environment variables,
- ** the client just sends those strings. Again each one is preceeded by
- ** its length as an unsigned short in network order. A length of zero
- ** is sent at the end, indicating there are no more strings.
- ** <LI>
- ** The fourth part is to send any data back and forth.
- ** The client reads data from stdin and sends it to the server, while
- ** simultaneously the response data from the server is read and then
- ** written to stdout. This continues until the client gets an EOF
- ** reading from the server. At that point the transaction is complete,
- ** the socket is closed, and the client exits.
- ** </OL>
- */
-
- public class NcgiRequest
- {
-
- private static final String MAGIC = "NCGI/1.0";
-
- private Hashtable hash;
-
- /** Read the initial NCGI request data.
- ** @param in the stream to read the request data from
- ** @exception NcgiException if there's a problem
- */
- public NcgiRequest( InputStream in, NcgiServer ncgiServer ) throws NcgiException
- {
- hash = new Hashtable();
- DataInputStream din = new DataInputStream( in );
- try
- {
- // Read and check magic.
- String magic = readString( din );
- if ( ! magic.equals( MAGIC ) )
- throw new NcgiException( "bad magic" );
- // Read and check auth.
- byte[] auth = readBlock( din );
- if ( ! equalsBytes( auth, ncgiServer.authBytes ) )
- throw new NcgiException( "bad auth" );
- // Read environment variables.
- while ( true )
- {
- String env = readString( din );
- if ( env.length() == 0 )
- break;
- int eq = env.indexOf( '=' );
- if ( eq != -1 )
- {
- String name = env.substring( 0, eq );
- String val = env.substring( eq + 1 );
- hash.put( name, val );
- }
- }
- // That'll do it.
- }
- catch (EOFException eof) {}// this means its time to leave
- catch ( IOException e )
- {
- throw new NcgiException(
- "problem reading request: " + e.toString() );
- }
- }
-
-
- /** Read a string, preceeded by its length as an unsigned short
- ** in network order.
- */
- private String readString( DataInputStream din ) throws IOException
- {
- byte[] b = readBlock( din );
- return new String( b, 0 );
- }
-
-
- /** Read a block of bytes, preceeded by its length as an unsigned short
- ** in network order.
- */
- private byte[] readBlock( DataInputStream din ) throws IOException
- {
- int len = din.readUnsignedShort();
- byte[] b = new byte[len];
- din.readFully( b );
- return b;
- }
-
-
- /** Utility routine to check two byte arrays for equality.
- */
- public static boolean equalsBytes( byte[] a, byte[] b )
- {
- if ( a.length != b.length )
- return false;
- for ( int i = 0; i < a.length; ++i )
- if ( a[i] != b[i] )
- return false;
- return true;
- }
-
-
- /** Get the value of the specified NCGI variable, which is actually
- ** just the identically-named CGI environment variable.
- */
- public String getVar( String name )
- {
- return (String) hash.get( name );
- }
-
-
- /**
- * Get a list of all NCGI variables.
- */
- public Enumeration getVars() {
- return hash.keys();
- }
- }
-